Amazon Bedrock を使ってイベント情報の要約を行い、Slack通知をさせてみた
こんにちは、森田です。
皆さん、EventBridge からイベントの通知を行う場合どのように構成していますか?
AWS Lambda を使ったイベント通知や EventBridge から直接APIを実行するような構成が考えられるかと思います。
どちらの構成であってもイベント情報から必要な情報のみを取得して通知を行うことになると思います。
この「イベント情報から必要な情報のみを取得」する作業では、JSONのパスミスなどで上手く通知ができない、エラーが発生してしまうことが度々ありましたので、もっと楽に通知構成ができないかを考えてみました。
考えた構成
以下のような EventBridge から Step Functions を実行する構成を考えました。
Amazon Bedrock
Amazon Bedrock では、EventBridge から送信されたイベント情報の要約を行います。
今回は、生成AIモデルは、 anthropic.claude-3-5-sonnet-20240620-v1 を利用し、以下のようなプロンプトを与えてみることにしました。
以下の情報は、AWSにおけるイベント情報です。
重要な情報のみに要約を行い、AWSアカウント保有者が必要なアクションがあれば、記述してください。
---
source: ${source}
resources: ${resources}
detail: ${detail}
やってみる
リソースの作成
以下のCloudFormationでリソースの作成を行いました。
CloudFormationテンプレート
AWSTemplateFormatVersion: "2010-09-09"
Description: Notify Step Functions
Parameters:
Prompt:
Type: String
ChannelId:
Type: String
ApiKeyValue:
Type: String
NoEcho: true
Resources:
SlackConnection:
Type: AWS::Events::Connection
Properties:
AuthorizationType: API_KEY
Description: Slack Connection
AuthParameters:
ApiKeyAuthParameters:
ApiKeyName: "Authorization"
ApiKeyValue: !Sub "Bearer ${ApiKeyValue}"
StateMachineRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Sid: StepFunctionsAssumeRolePolicy
Effect: Allow
Principal:
Service: "states.amazonaws.com"
Action: sts:AssumeRole
Path: /
Policies:
- PolicyName: "EventBridgeRetrieveConnectionCredentialsScopedAccessPolicy"
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- events:RetrieveConnectionCredentials
Resource: !Sub "${SlackConnection.Arn}"
- Effect: Allow
Action:
- secretsmanager:GetSecretValue
- secretsmanager:DescribeSecret
Resource: !Sub "${SlackConnection.SecretArn}"
- PolicyName: "StepFunctionsInvokeHttpEndpointScopedAccessPolicy"
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- states:InvokeHTTPEndpoint
Resource: !Sub "arn:aws:states:${AWS::Region}:${AWS::AccountId}:stateMachine:*"
Condition:
StringEquals:
"states:HTTPEndpoint":
- "https://slack.com/api/chat.postMessage"
"states:HTTPMethod":
- "POST"
- PolicyName: "XRayAccessPolicy"
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- xray:PutTraceSegments
- xray:PutTelemetryRecords
- xray:GetSamplingRules
- xray:GetSamplingTargets
Resource: "*"
- PolicyName: "BedrockInvokeModel"
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- bedrock:InvokeModel
Resource: !Sub "arn:aws:bedrock:${AWS::Region}::foundation-model/anthropic.claude-3-5-sonnet-20240620-v1:0"
NotifyStateMachine:
Type: AWS::StepFunctions::StateMachine
Properties:
RoleArn:
Fn::GetAtt: [ StateMachineRole, Arn ]
DefinitionString: !Sub
- |-
{
"Comment": "A description of my state machine",
"StartAt": "claude-3-5-sonnet-20240620",
"States": {
"claude-3-5-sonnet-20240620": {
"Type": "Task",
"Resource": "arn:aws:states:::bedrock:invokeModel",
"Parameters": {
"ModelId": "arn:aws:bedrock:${Region}::foundation-model/anthropic.claude-3-5-sonnet-20240620-v1:0",
"Body": {
"anthropic_version": "bedrock-2023-05-31",
"max_tokens": 4096,
"messages": [
{
"role": "user",
"content": [
{
"type": "text",
"text.$": "States.Format('${Prompt}---detail-type: {}\nsource: {}\nresources: {}\ndetail: {}', $.detail-type, $.source, $.resources, $.detail)"
}
]
}
]
}
},
"Next": "Call third-party API"
},
"Call third-party API": {
"Type": "Task",
"Resource": "arn:aws:states:::http:invoke",
"Parameters": {
"ApiEndpoint": "https://slack.com/api/chat.postMessage",
"Method": "POST",
"Authentication": {
"ConnectionArn": "${ConnectionArn}"
},
"RequestBody": {
"channel": "${ChannelId}",
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text.$": "$.Body.content[0].text"
}
}
]
}
},
"Retry": [
{
"ErrorEquals": [
"States.ALL"
],
"BackoffRate": 2,
"IntervalSeconds": 1,
"MaxAttempts": 3,
"JitterStrategy": "FULL"
}
],
"End": true
}
}
}
- Region: !Sub "${AWS::Region}"
Prompt: !Ref Prompt
ConnectionArn: !Sub "${SlackConnection.Arn}"
ChannelId: !Ref ChannelId
動作確認
では、実際にEventBridgeルールを作成し、イベント情報のサマリが行われるかを確認してみます。
今回は、以下のような Security Hub Findingsのイベントに対して通知を行ってみます。
{
"source": ["aws.securityhub"],
"detail-type": ["Security Hub Findings - Imported"],
"detail": {
"findings": {
"ProductFields": {
"StandardsArn": ["arn:aws:securityhub:::standards/aws-foundational-security-best-practices/v/1.0.0"]
},
"Compliance": {
"Status": ["FAILED"]
}
}
}
}
ターゲットには、CloudFormationで作成したステートマシンを選択して、ルールの作成を完了させます。
あとは、イベントが発生するように、AWSリソースの変更を行います。
イベント発生後、Step Functionsが実行され、以下のような通知が行われました。
いい感じにサマリされていますね。
この構成で通知させる時の注意点
この構成であれば、Amazon Bedrock でいい感じにサマリを行ってくれますが、重要な情報が抜けてしまう可能性はゼロではありません。
また、通知頻度が多くなることが想定される場合は、この構成は向いていません。
通知のたびに、Amazon Bedrock の呼び出しが行われ、コスト増加につながる恐れがあります。
さいごに
Step Functions を利用することでサーバレスでイベント情報の要約を行い、Slack通知ができました。
この構成の使い所としては、検証環境など手っ取り早く通知構成を構築したい場合に有効かと思いますのでぜひ使ってみてください。